package flexo.graphic.entity;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;

import flexo.graphic.Geometry;

public abstract class DynamicMesh extends Entity
{
	private FloatBuffer vertices;
	private IntBuffer indices;
	private boolean updateGeometry;
	protected int numVertices;
	protected int numIndices;	
	
	protected void setIndex(int index, int value)
	{
		indices.position(index);
		indices.put(value);
		updateGeometry = true;
	}
	
	protected void setVertexPosition(int vertex, float x, float y, float z)
	{
		vertices.position(Geometry.VERTEX_SIZE * vertex);
		vertices.put(x);
		vertices.position((Geometry.VERTEX_SIZE * vertex)+1);
		vertices.put(y);
		vertices.position((Geometry.VERTEX_SIZE * vertex)+2);
		vertices.put(z);
		updateGeometry = true;
	}
	
	protected void setVertexNormal(int vertex, float nx, float ny, float nz)
	{
		vertices.position((Geometry.VERTEX_SIZE * vertex)+3);
		vertices.put(nx);
		vertices.position((Geometry.VERTEX_SIZE * vertex)+4);
		vertices.put(ny);
		vertices.position((Geometry.VERTEX_SIZE * vertex)+5);
		vertices.put(nz);		
		updateGeometry = true;
	}
	
	protected void setVertexColor(int vertex, float r, float g, float b, float a)
	{
		vertices.position((Geometry.VERTEX_SIZE * vertex)+6);
		vertices.put(r);
		vertices.position((Geometry.VERTEX_SIZE * vertex)+7);
		vertices.put(g);
		vertices.position((Geometry.VERTEX_SIZE * vertex)+8);
		vertices.put(b);
		vertices.position((Geometry.VERTEX_SIZE * vertex)+9);
		vertices.put(a);
		updateGeometry = true;
	}
	
	protected void setVertexTexCoord(int vertex, float u, float v)
	{
		vertices.position((Geometry.VERTEX_SIZE * vertex)+10);
		vertices.put(u);
		vertices.position((Geometry.VERTEX_SIZE * vertex)+11);
		vertices.put(v);
		updateGeometry = true;
	}
	
	@Override
	public void update()
	{
		if (updateGeometry)
		{
			indices.rewind();
			vertices.rewind();
			this.geom.setIndices(indices);
			this.geom.setVertices(vertices);
			updateGeometry = false;
		}
	}
	
	protected void init(int numVertices, int numIndices, int updateType)
	{
		this.numIndices = numIndices;
		this.numVertices = numVertices;
		
		vertices = BufferUtils.createFloatBuffer(12 * numVertices); // 12bytes * n vertices
		indices = BufferUtils.createIntBuffer(numIndices);
		
		float[] vertex = new float[12]; // Each vertex holds 12 bytes
		
		for (int i = 0; i < numVertices; ++i)
		{
			vertex[0] = 0; vertex[1] = 0; vertex[2] = 0.0f;	// Position
			vertex[3] = 0.0f; vertex[4] = 0.0f; vertex[5] = 1.0f;	// Normal
			vertex[6] = 1.0f; vertex[7] = 1.0f; vertex[8] = 1.0f; vertex[9] = 1.0f;	// RGBA
			vertex[10] = 0.0f; vertex[11] = 1.0f;	// TexCoord
			vertices.put(vertex);
		}

		vertices.rewind();
		
		for (int i = 0; i < numIndices; ++i)
		{
			indices.put(0);
		}
		
		indices.rewind();
		
		super.init(new Geometry(vertices,indices,numIndices,updateType));
		updateGeometry = false;
	}
}
